﻿using System;
using System.Collections.Generic;
using System.Linq;
using NETDeob.Core.Engine;

namespace NETDeob.Core.Deobfuscators.Confuser._1_7
{
    internal class Cleaner : IRoutine
    {
        #region Routine Information

        public string Description
        {
            get { return "Clean Assembly"; }
        }

        public Dictionary<Func<Boolean>, String> Phases
        {
            get
            {
                return new Dictionary<Func<Boolean>, String>
                {
                    {Phase1, ".cctor Cleaning"},
                    {Phase2, "Watermark Cleaning"}
                };
            }
        }

        #endregion

        #region Phases

        private Boolean Phase1()
        {
            try
            {
                Settings.TargetAssemblyDef.Modules[0].Types[0].Methods.RemoveAt(0); // Remove .cctor

                // TODO:Exclude Non-Confuser Methods
                Settings.TargetAssemblyDef.Modules[0].Types[0].Methods.Clear();

                return true;
            }
            catch (Exception exception)
            {
                Logger.Exception(exception.Message, 2);
                return false;
            }
        }

        private Boolean Phase2()
        {
            try
            {
                //Remove Module Attribute
                Settings.TargetAssemblyDef.Modules[0].CustomAttributes.Remove(
                    Settings.TargetAssemblyDef.Modules[0].CustomAttributes.First(
                        watermarkAttribute => watermarkAttribute.AttributeType.Name == "ConfusedByAttribute"));

                // Remove Type
                Settings.TargetAssemblyDef.Modules[0].Types.Remove(
                    Settings.TargetAssemblyDef.Modules[0].Types.First(
                        watermarkType => watermarkType.Name == "ConfusedByAttribute"));

                return true;
            }
            catch (Exception exception)
            {
                Logger.Exception(exception.Message, 2);
                return false;
            }
        }

        #endregion
    }
}